package com.opgea.crm.services.security;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.opgea.crm.common.constant.ApplicationConstant;
import com.opgea.crm.common.vo.ResourceDetailsVo;
import com.opgea.crm.domain.entities.security.CrmUser;
import com.opgea.crm.domain.entities.security.Group;
import com.opgea.crm.domain.entities.security.ResourceDetails;
import com.opgea.crm.domain.entities.security.Role;
import com.opgea.crm.domain.modal.UserSessionData;
import com.opgea.crm.repository.security.ResourceDetailsRepository;

@Service
public class ResourceDetailsServiceImpl implements ResourceDetailsService{

	@Autowired
	ResourceDetailsRepository resourceDetailsRepository;
	
	@Autowired
	CrmUserServiceImpl userService;

	public void create(ResourceDetails resourceDetails) {
		resourceDetailsRepository.create(resourceDetails);
	}

	public ResourceDetails find(Long id) {
		return resourceDetailsRepository.find(id);
	}

	public List<ResourceDetailsVo> findAll() {
		List<ResourceDetails> resources =  resourceDetailsRepository.findAll();
		List<ResourceDetailsVo> resourceVoList = new ArrayList<ResourceDetailsVo>();
		for(ResourceDetails rd : resources){
			resourceVoList.add(new ResourceDetailsVo(
					rd.getId(),
					rd.getRole().getName(),
					rd.getResource().getResourceName(),
					rd.getCreate(), rd.getRead(), rd.getUpdate(), rd.getDelete()
					));
		}
		return resourceVoList;
	}

	public void update(ResourceDetails resourceDetails) {
		resourceDetailsRepository.update(resourceDetails);
	}

	public void remove(Long id) {
		resourceDetailsRepository.remove(id);
	}

	public List<ResourceDetailsVo> findByRole(Long roleId) {
		List<ResourceDetails> resources =  resourceDetailsRepository.findByRole(roleId);
		List<ResourceDetailsVo> resourceVoList = new ArrayList<ResourceDetailsVo>();
		for(ResourceDetails rd : resources){
			resourceVoList.add(new ResourceDetailsVo(
					rd.getId(),
					rd.getRole().getName(),
					rd.getResource().getResourceName(),
					rd.getCreate(), rd.getRead(), rd.getUpdate(), rd.getDelete()
					));
		}
		return resourceVoList;
	}

	public UserSessionData getAuthoritiesDetails() {
		CrmUser currentUser = userService.getCurrentLoggedInUser();
		
		List<Group> groups = currentUser.getGroups();
		Map<String, Map<String, Boolean>> resourceMap = new HashMap<String, Map<String, Boolean>>();
		if(groups != null){
			for(Group group : groups){
				List<Role> roles = group.getRoles();
				for(Role role : roles){
					//Role myRole = currentUser.getRole();
			    	List<ResourceDetails> resourceDetailsList = resourceDetailsRepository.findByRole(role.getId());
			    	
				    	
				    for(ResourceDetails resourceDetails : resourceDetailsList){
					   	Map<String, Boolean> detailsMap = new HashMap<String, Boolean>();
					   	String resourceName = resourceDetails.getResource().getResourceName();
					   	if(resourceMap.containsKey(resourceName)){
					   		
					   		boolean create = resourceMap.get(resourceName).get(ApplicationConstant.CREATE);
					   		boolean read = resourceMap.get(resourceName).get(ApplicationConstant.READ);
					   		boolean update = resourceMap.get(resourceName).get(ApplicationConstant.UPDATE);
					   		boolean remove = resourceMap.get(resourceName).get(ApplicationConstant.REMOVE);
					   		
					   		if(create == false){
					   			detailsMap.put(ApplicationConstant.CREATE, resourceDetails.getCreate());
					   		}
					   		if(create == true){
					   			detailsMap.put(ApplicationConstant.CREATE, true);
					   		}
					   		if(read == false){
					   			detailsMap.put(ApplicationConstant.READ, resourceDetails.getRead());
					   		}
					   		if(read == true){
					   			detailsMap.put(ApplicationConstant.READ, true);
					   		}
					   		if(update == false){
					   			detailsMap.put(ApplicationConstant.UPDATE, resourceDetails.getUpdate());
					   		}
					   		if(update == true){
					   			detailsMap.put(ApplicationConstant.UPDATE, true);
					   		}
					   		if(remove == false){
					   			detailsMap.put(ApplicationConstant.REMOVE, resourceDetails.getDelete());
					   		}
					   		if(remove == true){
					   			detailsMap.put(ApplicationConstant.REMOVE, true);
					   		}
					   		resourceMap.put(resourceDetails.getResource().getResourceName(), detailsMap);				   		
					   	}else{
					   		detailsMap.put(ApplicationConstant.CREATE, resourceDetails.getCreate());
					   		detailsMap.put(ApplicationConstant.READ, resourceDetails.getRead());
					   		detailsMap.put(ApplicationConstant.UPDATE, resourceDetails.getUpdate());
					   		detailsMap.put(ApplicationConstant.REMOVE, resourceDetails.getDelete());
					   		resourceMap.put(resourceDetails.getResource().getResourceName(), detailsMap);
					   	}
				    }				
				}
			}  
		}
			
    	UserSessionData userSessionData = new UserSessionData();
    	userSessionData.setEmailId(currentUser.getEmail());
    	userSessionData.setUserName(currentUser.getUserName());
    	userSessionData.setRoleName("NON");
    	if(groups != null && groups.size() > 0){
    		userSessionData.setRoleName(groups.get(0).getName());	
    	}
    	userSessionData.setResourceDetails(resourceMap);
		return userSessionData;
	}
}
